using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using System.Threading;
namespace ReefinDotNet
{
    partial class Program
    {
        private Socket socket = null;
        public void webServer()
        {
            //Debug.Print("Webserver starting on thread: " + Thread.CurrentThread.ManagedThreadId);
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //Bind to IP
            try
            {
                socket.Bind(new IPEndPoint(IPAddress.Any, 80)); // port 80 is default web port
                socket.Listen(10);
            }
            catch
            {
                Debug.Print("Couldn't Bind & Listen");
            }
            while (true)
            {
                try
                {
                    using (Socket clientSocket = socket.Accept())
                    {
                        //Get clients IP
                        IPEndPoint clientIP = clientSocket.RemoteEndPoint as IPEndPoint;
                        EndPoint clientEndPoint = clientSocket.RemoteEndPoint;
                        int bytesReceived = clientSocket.Available;
                        #region dataReceived
                        if (bytesReceived > 0)
                        {
                            //Get request
                            byte[] buffer = new byte[bytesReceived];
                            int byteCount = clientSocket.Receive(buffer, bytesReceived, SocketFlags.None);
                            string request = new string(Encoding.UTF8.GetChars(buffer));
                            //Debug.Print(request);
                            //Compose a response
                            string firstLine = request.Substring(0, request.IndexOf('\n')); //Example "GET /activatedoor HTTP/1.1"
                            string[] words = firstLine.Split(' ');  //Split line into words
                            string command = string.Empty;
                            string response = string.Empty;
                            string header = string.Empty;
                            if (words.Length > 2)
                            {
                                words = words[1].Split('?'); //if we've got arguments, lets put them in a seperate Array
                                command = words[0].TrimStart('/');
                            }
                            if (command == "") // root of the server
                            {
                                command = "status";
                            }
                            switch (command.ToLower())
                            {
                                #region favicon
                                case "favicon.ico":
                                    header = "HTTP/1.0 410 Gone";
                                    clientSocket.Send(Encoding.UTF8.GetBytes(header), header.Length, SocketFlags.None);
                                    break;
                                #endregion
                                #region status
                                case "status":
                                    //Compose a response
                                    response = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>";
                                    response += "<status>";
                                    response += "<uptime>" + (DateTime.Now - startup).ToString() + "</uptime>";
                                    //response += "<logging>" + _logToXively + "</logging>";
                                    response += "<temps>";
                                    response += "<temp1>" + temp[0] + "</temp1>";
                                    response += "</temps>";
                                    response += "<memory>" + Debug.GC(true).ToString() + "</memory>";
                                    response += "<ato>";
                                    response += "<status>" + !(ATO.Read()) + "</status>";
                                    response += "<enabled>" + (_ATOEnabled.ToString()) + "</enabled>";
                                    response += "<lastRun>" + _lastFire + "</lastRun>";
                                    response += "</ato>";
                                    response += "<lights>";
                                    response += "<override>" + mainLights.Override.ToString() + "</override>";
                                    response += "<light1>";
                                    response += "<ch1>" + mainLights.getPower(0) + "</ch1>";
                                    response += "<ch2>" + mainLights.getPower(1) + "</ch2>";
                                    response += "<ch3>" + mainLights.getPower(2) + "</ch3>";
                                    response += "<ch4>" + mainLights.getPower(3) + "</ch4>";
                                    response += "<ch5>" + mainLights.getPower(4) + "</ch5>";
                                    response += "</light1>";
                                    response += "</lights>";
                                    response += "</status>";
                                    header = "HTTP/1.0 200 OK\r\nContent-Type: text/xml; charset=utf-8\r\nContent-Length: " + response.Length.ToString() + "\r\nConnection: close\r\n\r\n";
                                    try
                                    {
                                        clientSocket.Send(Encoding.UTF8.GetBytes(header), header.Length, SocketFlags.None);
                                        clientSocket.Send(Encoding.UTF8.GetBytes(response), response.Length, SocketFlags.None);
                                    }
                                    catch { }
                                    break;
                                #endregion
                                #region Logging
                                case "logging":
                                    if (words.Length > 1)
                                    {
                                        if (words[1].ToLower() == "enable")
                                        {
                                            //_logToXively = true;
                                        }
                                        else if (words[1].ToLower() == "disable")
                                        {
                                            //_logToXively = false;
                                        }
                                    }
                                    goto case "status";
                                #endregion
                                #region Setlights
                                case "setlights":
                                    if (words.Length > 1)
                                    {
                                        string[] powers = new string[5];
                                        if (words[1].ToLower() == "reset")
                                        {
                                            try
                                            {
                                                mainLights.Override = false;
                                                //LCD.clear();
                                            }
                                            catch
                                            {
                                            }
                                            //mainLights.Step = 99; //only needed if using light phases
                                            //Debug.Print("Reset");
                                        }
                                        else
                                        {
                                            powers = words[1].Split('&');
                                            if (powers[0] != null || powers[1] != null || powers[2] != null || powers[3] != null || powers[4] != null)
                                            {
                                                try
                                                {
                                                    mainLights.Override = true;
                                                    //LCD.write("Light Override", 0, 1);
                                                    mainLights.fadeTo(Convert.ToInt32(powers[0]), Convert.ToInt32(powers[1]),Convert.ToInt32(powers[2]), Convert.ToInt32(powers[3]),Convert.ToInt32(powers[4]), 5);
                                                }
                                                catch
                                                { }
                                            }
                                            else
                                            {
                                                //Debug.Print("ERROR SETTING LIGHT MANUALLY");
                                            }
                                        }
                                    }
                                    /*response = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>";
                                    response += "<status>";
                                    response += "<lights>";
                                    response += "<override>" + mainLights.Override.ToString() + "</override>";
                                    response += "<light1>";
                                    response += "<ch1>" + mainLights.getPower(0) + "</ch1>";
                                    response += "<ch2>" + mainLights.getPower(1) + "</ch2>";
                                    response += "<ch3>" + mainLights.getPower(2) + "</ch3>";
                                    response += "<ch4>" + mainLights.getPower(3) + "</ch4>";
                                    response += "<ch5>" + mainLights.getPower(4) + "</ch5>";
                                    response += "</light1>";
                                    response += "</lights>";
                                    response += "</status>";
                                    header = "HTTP/1.0 200 OK\r\nContent-Type: text; charset=utf-8\r\nContent-Length: " + response.Length.ToString() + "\r\nConnection: close\r\n\r\n";
                                    try
                                    {
                                        clientSocket.Send(Encoding.UTF8.GetBytes(header), header.Length, SocketFlags.None);
                                        clientSocket.Send(Encoding.UTF8.GetBytes(response), response.Length, SocketFlags.None);
                                    }
                                    catch { }
                                    break; */
                                    goto case "status";
                                #endregion
                                #region reboot
                                case "reboot":
                                    header = "HTTP/1.0 204 No Content";
                                    clientSocket.Send(Encoding.UTF8.GetBytes(header), header.Length, SocketFlags.None);
                                    PowerState.RebootDevice(false);
                                    break;
                                #endregion
                                #region ATO
                                case "ato":
                                    if (words.Length > 1)
                                    {
                                        if (words[1].ToLower() == "on")
                                        {
                                            _ATOEnabled = true;
                                        }
                                        if (words[1].ToLower() == "off")
                                        {
                                            _ATOEnabled = false;
                                        }
                                    }
                                    goto case "status";
                                #endregion
                                #region Default
                                default:
                                    //Did not recognize command
                                    response = "Bad command";
                                    header = "HTTP/1.0 200 OK\r\nContent-Type: text; charset=utf-8\r\nContent-Length: " + response.Length.ToString() + "\r\nConnection: close\r\n\r\n";
                                    clientSocket.Send(Encoding.UTF8.GetBytes(header), header.Length, SocketFlags.None);
                                    clientSocket.Send(Encoding.UTF8.GetBytes(response), response.Length, SocketFlags.None);
                                    break;
                                #endregion
                            }
                        }
                        #endregion
                    }
                }
                catch (Exception ex)
                {
                    Debug.Print(ex.ToString());
                }
                Thread.Sleep(10);
            }
        }
    }
}
